'''
dionysus - a web based dialogue management framework
Copyright (C) 2011  Eugeniu Costetchi <eugeniu.costetchi (at) tudor.lu>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Created on Jan 14, 2011

'''
from random import sample
from DialogueManager.utils.log_utils import log_debug

class PlanExecutionException(Exception):
    pass

class PlanExecutor(object):
    '''
    classdocs
    '''

    def __init__(self, plan_graph, start, stop, context):
        '''
        Constructor
        '''
        self.plan = plan_graph
        self.start_action = start
        self.stop_action = stop
        self.execution_pointer = self.start_action
        self.context = context
        
    def execute_step(self):
        '''
            first check if the node has a successor defined, and if so executes it
            otherwise takes first successor available in the graph    
         '''
        log_debug("Executting:"+str(self.execution_pointer))
        self.execution_pointer.execute(self.context)
        if self.execution_pointer.succesor is not None:
            self.execution_pointer = self.execution_pointer.succesor
        else:
            succ = self.plan.successors(self.execution_pointer)
            if succ:
                if len(succ) == 1:
                    self.execution_pointer = succ[0]
                else:
                    self.execution_pointer = sample(succ,1)[0]
                    log_debug('Warning!, no execution pointer indicated when more than one successor Action exists in the plan')
            else:
                raise PlanExecutionException('No successor is defined for current action which is ' + str(self.execution_pointer))
            
#        if not isinstance(self.execution_pointer, StopPointer):
#            succ = self.plan.successors(self.execution_pointer)
#            if len(succ) == 1: 
#                self.execution_pointer = succ[0]
#            elif len(succ) > 1: 
#                if self.execution_pointer.succesor:
#                    self.execution_pointer = self.execution_pointer.succesor
#                else:
#                    raise PlanExecutionException('Next action is unknown. Current action is ' + str(self.execution_pointer)+' probably the plan does not have Stop Action')
#            else:
#                raise PlanExecutionException('No successor is defined for current action is ' + str(self.execution_pointer))

    def execute_until_break(self):
        self.execute_step()
        while not self.execution_pointer.is_breaking_execution:
            self.execute_step()
        
